package com.bnz.service.impl;

import com.bnz.dao.ClassesDao;
import com.bnz.dao.StudentDao;
import com.bnz.pojo.Classes;
import com.bnz.pojo.PageResult;
import com.bnz.pojo.Student;
import com.bnz.service.StudentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentDao studentDao;
    @Autowired
    private ClassesDao classesDao;

    //1. 查询所有学生
    @Override
    public List<Student> findAll() {
        //1.1 查询所有学生
        List<Student> students = studentDao.findAll();
        //1.2 将学生与班级名称绑定
        for (Student student : students) {
            Classes classes = classesDao.findById(student.getCid()).get();
            student.setCname(classes.getCname());
        }
        //1.3 返回
        return students;
    }

    //2. 分页查询
    @Override
    public PageResult<Student> findByPage(int page, int pageSize) {
        //2.1 开始分页查询
        Page<Student> studentPage = studentDao.findAll(PageRequest.of(page - 1, pageSize));
        System.out.println(studentPage);
        //2.2 将学生与班级名称绑定
        for (Student student : studentPage.getContent()) {
            Classes classes = classesDao.findById(student.getCid()).get();
            student.setCname(classes.getCname());
        }
        //2.3 返回PageResult对象
        return new PageResult<>(studentPage.getTotalElements(),studentPage.getContent());
    }

    //3. 条件查询带分页
    @Override
    public PageResult<Student> search(int page, int pageSize, Student vo) {
        //3.1 将查询条件封装到数组中
        List<Predicate> predicates = new ArrayList<>();
        Specification<Student> spec = new Specification<Student>() {
            //3.2 根据传入的参数将查询条件封装放到predicates集合中
            @Override
            public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                if (vo != null){
                    if (StringUtils.isNotBlank(vo.getSname())){
                        Predicate sname = cb.like(root.get("sname").as(String.class), "%" + vo.getSname() + "%");
                        predicates.add(sname);
                    }
                    if (StringUtils.isNotBlank(vo.getAddr())){
                        Predicate addr = cb.like(root.get("addr").as(String.class), "%" + vo.getAddr() + "%");
                        predicates.add(addr);
                    }
                    if (vo.getCid() != null && vo.getCid() != 0){
                        Predicate cid = cb.equal(root.get("cid").as(Integer.class), vo.getCid());
                        predicates.add(cid);
                    }
                }
                //3.3 将条件集合转换为数组
                Predicate[] predicatesArr = predicates.toArray(new Predicate[predicates.size()]);
                //3.4 返回
                return cb.and(predicatesArr);
            }
        };
        //3.5 开始分页查询
        Page<Student> studentPage = studentDao.findAll(spec, PageRequest.of(page - 1, pageSize));
        //3.6 将学生与班级名称绑定
        for (Student student : studentPage.getContent()) {
            Classes classes = classesDao.findById(student.getCid()).get();
            student.setCname(classes.getCname());
        }
        //3.7 返回PageResult对象
        return new PageResult<>(studentPage.getTotalElements(),studentPage.getContent());
    }

    //4. 添加学生
    @Override
    public void add(Student student) {
        studentDao.save(student);
    }

    //5. 修改学生
    @Override
    public void update(Student student) {
        studentDao.save(student);
    }

    //6. 删除学生
    @Override
    public void delete(Integer[] ids) {
        for (Integer id : ids) {
            studentDao.deleteById(id);
        }

    }
}
